;(function($){
			
	// 常量定义
	var CACHE_GRID = 'sngrid';
	
	// 创建表格
	function createTable(target){
		var options = $.data(target, CACHE_GRID).options;
		var columns = options.columns;
		
		// 创建表头
		var thead = target.createTHead().insertRow();
		$.each(columns, function(pos, ele){
			var cell = thead.appendChild(document.createElement('th'));
			$(cell).html(ele.title).attr('field', ele.field);
			if(ele.sortable){
				$(cell).addClass('sortable');
			}
			
			if(ele.sortable && ele.field == options.sortName){
				$(cell).addClass($.trim(options.sortOrder).toLowerCase());
			}
			
			// 隐藏列
			if(ele.hide){
				$(cell).css('display', 'none');
			}
		});
		
		if(options.lineNumber){
			thead.insertBefore(document.createElement('th'), thead.firstChild);
		}
		
		// 点击表头排序
		$(target).on('click', 'th', function(){
			
			// 非排序字段
			if(!$(this).hasClass('sortable')){
				return;
			}
			
			var target = $(this).closest('table')[0];
			var options = $.data(target, CACHE_GRID).options;
			
			var sortName = $(this).attr('field');
			var sortOrder = $(this).attr('sortOrder');
			
			if(sortName != options.sortName){
				options.sortName = sortName;
				sortOrder = 'asc';
			}else{
				sortOrder = sortOrder == 'asc' ? 'desc' : 'asc';
			}
			
			$(this).addClass(sortOrder).removeClass(sortOrder == 'asc' ? 'desc' : 'asc');
			options.sortOrder = sortOrder;
			$(this).attr('sortOrder', sortOrder).siblings().removeAttr('sortOrder').removeClass('asc desc');
			$(target).sngrid('reload');
		});
		
		// 释放内存
		options = null;
		columns = null;
	}
	
	// 创建grid面板
	function createGridPanel(target){
		
		var options = $.data(target, CACHE_GRID).options;
		
		// 创建外部包裹
		var grid_panel = $(target).wrap('<div class="ui-sngrid-grid"></div>').closest('div');
		var sngrid = grid_panel.wrap('<div class="ui-sngrid"></div>').closest('div.ui-sngrid');
		
		if(options.width && options.width != 'auto'){
			sngrid.outerWidth(options.width);
		}
		
		if(options.height && options.height != 'auto'){
			sngrid.outerHeight(options.height);
		}
		
		if(options.fit){
			sngrid.outerWidth(sngrid.parent().width());
			sngrid.outerHeight(sngrid.parent().height());
		}
		
		// 工具栏
		if(options.toolbar.length > 0){
			var toolbar = sngrid.prepend('<div class="ui-sngrid-toolbar"></div>').children('.ui-sngrid-toolbar');
			
			// 创建工具按钮
			$.each(options.toolbar, function(pos, ele) {
				
				if(typeof ele === 'string'){
					toolbar.append('<i>|</i>');
					return true;
				}
				
				var btn = toolbar.append('<a href="javascript:void(0)">' + ele.text + '</a>').children('a:last');
				btn.on('click', ele.handler);
			});
		}
		
		// 表头
		if(options.title){
			sngrid.prepend('<div class="ui-sngrid-header"><span class="ui-sngrid-header-title">' + 
							options.title + 
							'</span></div>');
		}
		
		// 分页面板
		if(options.pagination){
			sngrid.append('<div class="ui-sngrid-pager"><ul></ul></div>')
				  .find('.ui-sngrid-pager ul').on('click', 'li', function(){
				
				// 非可用分页按钮
				if(!$(this).is('[pagenum]')){
					return;
				}
				
				// 加载数据
				options.pageNum = +$(this).attr('pagenum');
				$(target).sngrid('reload');
			});
		}
	}

	function loadData(target, data){
		
		var options = $.data(target, CACHE_GRID).options;
		var columns = options.columns;
		
		var tbody = target.tBodies;
		tbody = (tbody == null || tbody.length == 0) ? target.createTBody() : tbody[0];
		
		// 先删掉原有数据
		while(tbody.rows && tbody.rows.length > 0){
			tbody.deleteRow(0);
		}
		
		var pager = $(target).closest('div.ui-sngrid').find('div.ui-sngrid-pager ul');
		// 暂无数据
		if(!(data.rows && data.rows.length)){
			var cell = tbody.insertRow(0).insertCell(0);
			cell.colSpan = columns.length;
			cell.appendChild(document.createTextNode(options.nodata));
			pager.empty().hide();
			return;
		}else{
			pager.show();
		}
			
		
		$.each(data.rows, function(rowPos, ele) {    
			var row = tbody.insertRow(rowPos);
			
			// 创建每行的单元格
			$.each(columns, function(pos, col){
				var cell = row.insertCell(pos);
				var html = ele[col.field];
				if(typeof col.formatter === 'function'){
					html = col.formatter.call(cell, ele, ele[col.field], rowPos, pos);
				}
				$(cell).html(html);
				
				// 添加单元格样式
				style(cell, col);
			});
			
			if(options.lineNumber){
				var lineCell = document.createElement('td');
				$(lineCell).addClass('lineNumber');
				lineCell.appendChild(document.createTextNode((options.pageNum - 1) * options.pageSize + rowPos + 1));
				row.insertBefore(lineCell, row.firstChild);
			}
			
		});
		
		// 隔行变色
		if(options.striped){
			$(target).find('tr:even').addClass('striped');
		}
		
		updatePager(target, data.total);
	}
	
	function style(cell, colConfig){
		
		cell = $(cell);
		
		// 单元格宽度
		if(colConfig.width !== undefined){
			cell.width(colConfig.width);
		}
		
		// 单元格对齐方式
		if(colConfig.align !== undefined){
			cell.css('text-align', colConfig.align);
		}
		
		// 隐藏列
		if(colConfig.hide){
			cell.css('display', 'none');
		}
	}
	
	function updatePager(target, total){
		
		var options = $.data(target, CACHE_GRID).options;
		var pagerPanel = $(target).closest('div.ui-sngrid').find('div.ui-sngrid-pager ul').empty();
		
		var pages = Math.ceil(total / options.pageSize);
		var pagenum = options.pageNum;
		
		var p = [];
		
		// 加入上一页
		if(pagenum > 1){
			p.push({
				text : '首页',
				pagenum : 1
			},{
				text : '上一页',
				pagenum : pagenum - 1
			});
		}
		
		var from = Math.max(1, pagenum - 5),
			to = Math.min(from + 9, pages);
		for(var i = from; i <= to; i++){
			p.push({
				text : i,
				pagenum : i
			});
		}
		
		// 加入下一页
		if(pagenum < pages){
			p.push({
				text : '下一页',
				pagenum : pagenum + 1
			},{
				text : '尾页',
				pagenum : pages
			});
		}
		
		$.each(p, function(pos, ele) {
			if(ele.pagenum == options.pageNum){
				pagerPanel.append('<li class="current">' + ele.text + '</li>');
			}else{
				pagerPanel.append('<li pagenum="' + ele.pagenum + '">' + ele.text + '</li>');
			}
		});
	}
	
	$.fn.sngrid = function(options, params){
		
		// 方法调用
		if(typeof options === 'string'){
			return $.fn.sngrid.methods[options].call(this, params);
		}
		
		// Grid初始化
		options = options || {};
		return this.each(function(){
			
			// 缓存配置项
			options = $.extend(true, {
				title:'',
				url:'',
				method : 'get',
				params:{},
				columns:[], // {field:'', title:'', hide:false, sortable:false, width:'', formatter:function(){}}
				data:{}, // {total:0, rows:[{//参考columns}]}
				width:'',
				height:'',
				lineNumber:true,
				pagination:true,
				pageSize:10,
				pageNum:1,
				sortName:'',
				sortOrder:'',
				striped:true,
				nodata:'暂无数据',
				toolbar:[] // {text:'', handler:function(){}}
			}, options);
			
			$.data(this, CACHE_GRID, {
				options : options
			});
			
			var target = this;
			createGridPanel(target);
			createTable(target);
			
			if(options.data.rows){
				loadData(target, options.data);
			}else{
				$(target).sngrid('load');
			}
		});
	};
	
	$.fn.sngrid.methods = {
		// 加载本地数据
		loadData : function(data){
			return this.each(function(){
				loadData(this, data);
			});
		},
		// 加载远程数据，pagenum重置为1
		load : function(params){
			return this.each(function(){
				var target = this;
				var options = $.data(target, CACHE_GRID).options;
				options.pageNum = 1;
				$.fn.sngrid.methods.reload.call($(target), params);
			});
			
		},
		// 与加载远程数据类似，但pagenum不变
		reload : function(params){
			
			params = params || {};
			
			return this.each(function(){
				var target = this;
				var options = $.data(target, CACHE_GRID).options;
				// 合并查询参数
				$.extend(true, options, {params : params});
				
				$.ajax({
					url : options.url,
					type : options.method,
					data: $.extend(options.params, {
						pagenum : options.pageNum,
						pagesize : options.pageSize,
						sort:options.sortName,
						order:options.sortOrder
					}),
					dataType:'json',
					success:function(data){
						loadData(target, data);
					},
					error:function(XMLHttpRequest, textStatus, errorThrown){
						
					}
				});
			});
		}
	};
})(jQuery);